﻿using SHZY.Common.Core.Manager;
using SHZY.Common.Core.Security;
using SHZY.ClayObject;
using SHZY.Common.Configuration;
using SHZY.Common.Models.NPOI;
using SHZY.DataEncryption;
using SHZY.Common.Enum;
using SHZY.Common.Extension;
using SHZY.Common.Filter;
using SHZY.Common.Models;
using SHZY.Common.Security;
using SHZY.DependencyInjection;
using SHZY.DynamicApiController;
using SHZY.FriendlyException;
using SHZY.Systems.Entitys.Permission;
using SHZY.Systems.Entitys.System;
using SHZY.Systems.Interfaces.System;
using SHZY.BaseData.Entitys.Dto.QmsBaseIpqcinspector;
using SHZY.Systems.Entitys.System;
using SHZY.BaseData.Entitys;
using SHZY.BaseData.Interfaces;
using SHZY.BaseData.Entitys.Entity;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using SHZY.Extend.Entitys;
using System.Linq;
using NPOI.SS.Formula.Functions;

namespace SHZY.BaseData;

/// <summary>
/// 业务实现：检验员分配.
/// </summary>
[ApiDescriptionSettings(Tag = "BaseData", Name = "QmsBaseIpqcinspector", Order = 200)]
[Route("api/BaseData/[controller]")]
public class QmsBaseIpqcinspectorService : IQmsBaseIpqcinspectorService, IDynamicApiController, ITransient
{
    /// <summary>
    /// 服务基础仓储.
    /// </summary>
    private readonly ISqlSugarRepository<QmsBaseIpqcinspectorEntity> _repository;
    private readonly ISqlSugarRepository<QmsBaseFactorystructureEntity> _repositoryFactory;
    private readonly ISqlSugarRepository<QmsBaseStationEntity> _repositoryStation;
    private readonly ISqlSugarRepository<QmsBaseArtrouteEntity> _repositoryArtroute;
    private readonly ISqlSugarRepository<QmsBaseArtroutedetailEntity> _repositoryModeling;
    private readonly ISqlSugarRepository<QmsBaseMaterialgroupEntity> _repositoryMaterialgroup;
    private readonly ISqlSugarRepository<UserEntity> _repositoryEmployee;
    private readonly ISqlSugarRepository<QmsBaseMaterialEntity> _repositoryMaterial;

    /// <summary>
    /// 多租户事务.
    /// </summary>
    private readonly ITenant _db;

    /// <summary>
    /// 数据接口服务.
    /// </summary>
    private readonly IDataInterfaceService _dataInterfaceService;

    /// <summary>
    /// 用户管理.
    /// </summary>
    private readonly IUserManager _userManager;

    /// <summary>
    /// 初始化一个<see cref="QmsBaseIpqcinspectorService"/>类型的新实例.
    /// </summary>
    public QmsBaseIpqcinspectorService(
        ISqlSugarRepository<QmsBaseIpqcinspectorEntity> qmsBaseIpqcinspectorRepository,
        ISqlSugarRepository<QmsBaseFactorystructureEntity> QmsBaserepositoryFactory,
        ISqlSugarRepository<QmsBaseStationEntity> QmsBaserepositoryStation,
        ISqlSugarRepository<QmsBaseArtrouteEntity> QmsBaserepositoryArtroute,
        ISqlSugarRepository<QmsBaseArtroutedetailEntity> QmsBaserepositoryModeling,
        ISqlSugarRepository<QmsBaseMaterialgroupEntity> QmsBaserepositoryMaterialgroup,
        ISqlSugarRepository<UserEntity> QmsBaserepositoryEmployee,
        ISqlSugarRepository<QmsBaseMaterialEntity> QmsBaserepositoryMaterial,
        IDataInterfaceService dataInterfaceService,
        ISqlSugarClient context,
        IUserManager userManager)
    {
        _repository = qmsBaseIpqcinspectorRepository;
        _repositoryFactory = QmsBaserepositoryFactory;
        _repositoryStation = QmsBaserepositoryStation;
        _repositoryArtroute = QmsBaserepositoryArtroute;
        _repositoryModeling = QmsBaserepositoryModeling;
        _repositoryMaterialgroup = QmsBaserepositoryMaterialgroup;
        _repositoryEmployee = QmsBaserepositoryEmployee;
        _repositoryMaterial = QmsBaserepositoryMaterial;

        _dataInterfaceService = dataInterfaceService;
        _db = context.AsTenant();
        _userManager = userManager;
    }

    /// <summary>
    /// 获取检验员分配.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<dynamic> GetInfo(string id)
    {
        var query = await _repository.FirstOrDefaultAsync(x => x.Id == id);
        var data = query.Adapt<QmsBaseIpqcinspectorInfoOutput>();
        data.modelingId = query.ProcessId;
        return data;
    }

    /// <summary>
    /// 获取检验员分配列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("")]
    public async Task<dynamic> GetList([FromQuery] QmsBaseIpqcinspectorListQueryInput input)
    {

        var Section = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Section")
            .ToListAsync();

        var Workshop = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Workshop")
            .ToListAsync();

        var Team = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Team")
            .ToListAsync();

        var Station = await _repositoryStation.Context.Queryable<QmsBaseStationEntity>().ToListAsync();

        var Artroute = await _repositoryArtroute.Context.Queryable<QmsBaseArtrouteEntity>().ToListAsync();

        var Modeling = await _repositoryModeling.Context.Queryable<QmsBaseArtroutedetailEntity>().ToListAsync();

        var Materialgroup = await _repositoryMaterialgroup.Context.Queryable<QmsBaseMaterialgroupEntity>().ToListAsync();

        var Employee = await _repositoryEmployee.Context.Queryable<UserEntity>()
            .ToListAsync();

        var Material = await _repositoryMaterial.Context.Queryable<QmsBaseMaterialEntity>()
            .ToListAsync();

        List<string> empcode = new List<string>();
        List<string> matcode = new List<string>();

        foreach (var item in Employee)
        {
            if (!string.IsNullOrEmpty(input.employee_fullName))
            {
                if (item.RealName.Contains(input.employee_fullName) || item.Account.Contains(input.employee_fullName))
                {
                    empcode.Add(item.Account);
                }
            }
        }
        foreach (var item in Material)
        {
            if (!string.IsNullOrEmpty(input.material_name))
            {
                if (item.Name.Contains(input.material_name) || item.Code.Contains(input.material_name))
                {
                    matcode.Add(item.Code);
                }
            }
        }

        var data = await _repository.Context.Queryable<QmsBaseIpqcinspectorEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.type), x => x.Type.Contains(input.type))
            .WhereIF(!string.IsNullOrEmpty(input.material_name), x => matcode.Contains(x.MaterialCode))
            .WhereIF(!string.IsNullOrEmpty(input.employee_fullName), x => empcode.Contains(x.EmployeeCode))
            .Where(it => it.DeleteMark == null)
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id)
            .OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort)
            .Skip((input.currentPage - 1) * input.pageSize)
            .Take(input.pageSize)
            .ToListAsync();

        List<QmsBaseIpqcinspectorListOutput> listOut = new List<QmsBaseIpqcinspectorListOutput>();
        foreach (var item in data)
        {
            var team = Team.Where(s => s.Id == item.TeamId).ToList();
            var section = Section.Where(s => s.Id == item.WorkshopSectionId).ToList();
            var workshop = Workshop.Where(s => s.Id == item.WorkshopId).ToList();
            var station = Station.Where(s => s.Id == item.StationId).ToList();
            var artroute = Artroute.Where(s => s.Id == item.ArtrouteId).ToList();
            var modeling = Modeling.Where(s => s.Id == item.ProcessId).ToList();
            var materialgroup = Materialgroup.Where(s => s.Code == item.MaterialGroupCode).ToList();
            var material = Material.Where(it => it.Code == item.MaterialCode).ToList();
            var employee = Employee.Where(it => it.Account == item.EmployeeCode).ToList();

            QmsBaseIpqcinspectorListOutput outdata = new QmsBaseIpqcinspectorListOutput()
            {
                id = item.Id,
                type = item.Type == "C" ? "C" : item.Type == "X" ? "X" : "S",
                enabledMark = item.EnabledMark == 0 ? "停用" : "正常",
                teamId = "",
                workshopSectionId = "",
                workshopId = "",
                stationId = "",
                artrouteId = "",
                modelingId = "",
                materialgroupCode = "",
                materialCode = "",
                employeeCode = ""
            };

            if (team.Count > 0)
            {
                outdata.teamId = team.First().FullName;
            }
            if (section.Count > 0)
            {
                outdata.workshopSectionId = section.First().FullName;
            }
            if (workshop.Count > 0)
            {
                outdata.workshopId = workshop.First().FullName;
            }

            if (Station.Count > 0)
            {
                outdata.stationId = Station.First().FullName;
            }
            if (artroute.Count > 0)
            {
                outdata.artrouteId = artroute.First().FullName;
            }
            if (modeling.Count > 0)
            {
                outdata.modelingId = modeling.First().FullName;
            }
            if (materialgroup.Count > 0)
            {
                outdata.materialgroupCode = materialgroup.First().Name;
            }
            if (material.Count > 0)
            {
                outdata.materialCode = material.First().Name;
            }
            if (employee.Count > 0)
            {
                outdata.employeeCode = employee.First().RealName;
            }

            listOut.Add(outdata);
        }

        PageResultNew reNew = new PageResultNew()
        {
            list = listOut,
            pageIndex = input.currentPage,
            pageSize = input.pageSize,
            total = listOut.Count
        };

        return reNew;
    }

    /// <summary>
    /// 新建检验员分配.
    /// </summary>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPost("")]
    public async Task Create([FromBody] QmsBaseIpqcinspectorCrInput input)
    {
        var entity = input.Adapt<QmsBaseIpqcinspectorEntity>();
        entity.ProcessId = input.modelingId;
        entity.StationId = input.stationId;
        var isOk = await _repository.Context
            .Insertable(entity)
            .IgnoreColumns(ignoreNullColumn: true)
            .CallEntityMethod(m => m.Creator())
            .ExecuteCommandAsync();

        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1000);
    }

    /// <summary>
    /// 获取检验员分配无分页列表.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    private async Task<dynamic> GetNoPagingList([FromQuery] QmsBaseIpqcinspectorListQueryInput input)
    {
        var Section = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Section")
            .ToListAsync();

        var Workshop = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Workshop")
            .ToListAsync();

        var Team = await _repositoryFactory.Context.Queryable<QmsBaseFactorystructureEntity>()
            .Where(x => x.Type == "Team")
            .ToListAsync();

        var Station = await _repositoryStation.Context.Queryable<QmsBaseStationEntity>().ToListAsync();

        var Artroute = await _repositoryArtroute.Context.Queryable<QmsBaseArtrouteEntity>().ToListAsync();

        var Modeling = await _repositoryModeling.Context.Queryable<QmsBaseArtroutedetailEntity>().ToListAsync();

        var Materialgroup = await _repositoryMaterialgroup.Context.Queryable<QmsBaseMaterialgroupEntity>().ToListAsync();

        var Employee = await _repositoryEmployee.Context.Queryable<UserEntity>()
            .ToListAsync();

        var Material = await _repositoryMaterial.Context.Queryable<QmsBaseMaterialEntity>()
            .ToListAsync();

        if (!string.IsNullOrEmpty(input.material_name))
        {
            Material
                .Where(it => it.Name.Contains(input.material_name) || it.Code.Contains(input.material_name))
                .Select(it => new { it.Code });
        }

        if (!string.IsNullOrEmpty(input.employee_fullName))
        {
            Employee
                .Where(it => it.RealName.Contains(input.employee_fullName) || it.Account.Contains(input.employee_fullName))
                .Select(it => new { it.Account });
        }

        List<string> empcode = new List<string>();
        List<string> matcode = new List<string>();

        foreach (var item in Employee)
        {
            empcode.Add(item.Account);
        }
        foreach (var item in Material)
        {
            matcode.Add(item.Code);
        }

        var data = await _repository.Context.Queryable<QmsBaseIpqcinspectorEntity>()
            .WhereIF(!string.IsNullOrEmpty(input.type), x => x.Type.Contains(input.type))
            .WhereIF(!string.IsNullOrEmpty(input.material_name), x => matcode.Contains(x.MaterialCode))
            .WhereIF(!string.IsNullOrEmpty(input.employee_fullName), x => empcode.Contains(x.EmployeeCode))
            .Where(it => it.DeleteMark == null)
            .OrderByIF(string.IsNullOrEmpty(input.sidx), it => it.Id)
            .OrderByIF(!string.IsNullOrEmpty(input.sidx), it => input.sidx + " " + input.sort)
            .ToListAsync();

        List<QmsBaseIpqcinspectorListOutput> listOut = new List<QmsBaseIpqcinspectorListOutput>();
        foreach (var item in data)
        {
            var team = Team.Where(s => s.Id == item.TeamId).ToList();
            var section = Section.Where(s => s.Id == item.WorkshopSectionId).ToList();
            var workshop = Workshop.Where(s => s.Id == item.WorkshopId).ToList();
            var station = Station.Where(s => s.Id == item.StationId).ToList();
            var artroute = Artroute.Where(s => s.Id == item.ArtrouteId).ToList();
            var modeling = Modeling.Where(s => s.Id == item.ProcessId).ToList();
            var materialgroup = Materialgroup.Where(s => s.Code == item.MaterialGroupCode).ToList();
            var material = Material.Where(it => it.Code == item.MaterialCode).ToList();
            var employee = Employee.Where(it => it.Account == item.EmployeeCode).ToList();

            QmsBaseIpqcinspectorListOutput outdata = new QmsBaseIpqcinspectorListOutput()
            {
                id = item.Id,
                type = item.Type == "C" ? "C" : item.Type == "X" ? "X" : "S",
                enabledMark = item.EnabledMark == 0 ? "停用" : "正常",
                teamId = "",
                workshopSectionId = "",
                workshopId = "",
                stationId = "",
                artrouteId = "",
                modelingId = "",
                materialgroupCode = "",
                materialCode = "",
                employeeCode = ""
            };

            if (team.Count > 0)
            {
                outdata.teamId = team.First().FullName;
            }
            if (section.Count > 0)
            {
                outdata.workshopSectionId = section.First().FullName;
            }
            if (workshop.Count > 0)
            {
                outdata.workshopId = workshop.First().FullName;
            }

            if (Station.Count > 0)
            {
                outdata.stationId = Station.First().FullName;
            }
            if (artroute.Count > 0)
            {
                outdata.artrouteId = artroute.First().FullName;
            }
            if (modeling.Count > 0)
            {
                outdata.modelingId = modeling.First().FullName;
            }
            if (materialgroup.Count > 0)
            {
                outdata.materialgroupCode = materialgroup.First().Name;
            }
            if (material.Count > 0)
            {
                outdata.materialCode = material.First().Name;
            }
            if (employee.Count > 0)
            {
                outdata.employeeCode = employee.First().RealName;
            }

            listOut.Add(outdata);
        }

        return listOut;
    }

    /// <summary>
    /// 导出检验员分配.
    /// </summary>
    /// <param name="input">请求参数.</param>
    /// <returns></returns>
    [HttpGet("Actions/Export")]
    public async Task<dynamic> Export([FromQuery] QmsBaseIpqcinspectorListQueryInput input)
    {
        var exportData = new List<QmsBaseIpqcinspectorListOutput>();
        if (input.dataType == 0)
            exportData = Clay.Object(await GetList(input)).Solidify<PageResult<QmsBaseIpqcinspectorListOutput>>().list;
        else
            exportData = await GetNoPagingList(input);
        List<ParamsModel> paramList = "[{\"value\":\"检验类型\",\"field\":\"type\"},{\"value\":\"车间\",\"field\":\"workshopId\"},{\"value\":\"班组\",\"field\":\"teamId\"},{\"value\":\"工段\",\"field\":\"workshopSectionId\"},{\"value\":\"工位\",\"field\":\"stationId\"},{\"value\":\"⼯艺建模\",\"field\":\"artrouteId\"},{\"value\":\"工序\",\"field\":\"processId\"},{\"value\":\"物料\",\"field\":\"materialCode\"},{\"value\":\"物料组\",\"field\":\"materialGroupCode\"},{\"value\":\"员工号\",\"field\":\"employeeCode\"},]".ToList<ParamsModel>();
        ExcelConfig excelconfig = new ExcelConfig();
        excelconfig.FileName = "检验员分配.xls";
        excelconfig.HeadFont = "微软雅黑";
        excelconfig.HeadPoint = 10;
        excelconfig.IsAllSizeColumn = true;
        excelconfig.ColumnModel = new List<ExcelColumnModel>();
        foreach (var item in input.selectKey.Split(',').ToList())
        {
            var isExist = paramList.Find(p => p.field == item);
            if (isExist != null)
                excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
        }

        var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName;
        ExcelExportHelper<QmsBaseIpqcinspectorListOutput>.Export(exportData, excelconfig, addPath);
        var fileName = _userManager.UserId + "|" + addPath + "|xls";
        return new
        {
            name = excelconfig.FileName,
            url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "SHZY")
        };
    }

    /// <summary>
    /// 批量删除检验员分配.
    /// </summary>
    /// <param name="ids">主键数组.</param>
    /// <returns></returns>
    [HttpPost("batchRemove")]
    public async Task BatchRemove([FromBody] List<string> ids)
    {
        var entitys = await _repository.Context.Queryable<QmsBaseIpqcinspectorEntity>().In(it => it.Id, ids).ToListAsync();

        if (entitys.Count > 0)
        {
            try
            {
                // 开启事务
                _db.BeginTran();

                // 批量删除​缺陷类别
                var isOk = await _repository.Context
                .Updateable<QmsBaseIpqcinspectorEntity>()
                .SetColumns(it => new QmsBaseIpqcinspectorEntity()
                {
                    DeleteTime = DateTime.Now,
                    DeleteMark = 1,
                    DeleteUserId = _userManager.UserId
                }).Where(it => ids.Contains(it.Id))
                .ExecuteCommandHasChangeAsync();

                // 关闭事务
                _db.CommitTran();
            }
            catch (Exception)
            {
                // 回滚事务
                _db.RollbackTran();

                throw Oops.Oh(ErrorCode.COM1002);
            }
        }
    }

    /// <summary>
    /// 更新检验员分配.
    /// </summary>
    /// <param name="id">主键值.</param>
    /// <param name="input">参数.</param>
    /// <returns></returns>
    [HttpPut("{id}")]
    public async Task Update(string id, [FromBody] QmsBaseIpqcinspectorUpInput input)
    {
        var entity = input.Adapt<QmsBaseIpqcinspectorEntity>();
        entity.ProcessId = input.modelingId;
        entity.StationId = input.stationId;
        var isOk = await _repository.Context.Updateable(entity).UpdateColumns(it => new
        {
            it.Type,
            it.WorkshopId,
            it.TeamId,
            it.WorkshopSectionId,
            it.StationId,
            it.ArtrouteId,
            it.ProcessId,
            it.MaterialCode,
            it.MaterialGroupCode,
            it.EmployeeCode,
            it.EnabledMark,
        }).ExecuteCommandAsync();
        if (!(isOk > 0)) throw Oops.Oh(ErrorCode.COM1001);
    }

    /// <summary>
    /// 删除检验员分配.
    /// </summary>
    /// <returns></returns>
    [HttpDelete("{id}")]
    public async Task Delete(string id)
    {
        var isOk = await _repository.Context.Updateable<QmsBaseIpqcinspectorEntity>()
           .SetColumns(it => new QmsBaseIpqcinspectorEntity()
           {
               DeleteTime = DateTime.Now,
               DeleteMark = 1,
               DeleteUserId = _userManager.UserId
           }).Where(x => x.Id == id)
           .ExecuteCommandHasChangeAsync();

        if (!isOk) throw Oops.Oh(ErrorCode.COM1002);
    }

    public class PageResultNew
    {
        //
        // 摘要:
        //     页码.
        public int pageIndex { get; set; }

        //
        // 摘要:
        //     页容量.
        public int pageSize { get; set; }

        //
        // 摘要:
        //     总条数.
        public int total { get; set; }

        //
        // 摘要:
        //     数据.
        public List<QmsBaseIpqcinspectorListOutput> list { get; set; }
    }
}